#!/bin/bash
SCRIPT_PATH=$(cd "$(dirname "$0")" || exit; pwd)
SCRIPT_NAME=$(basename $0)
BACKUP_PATH=${SCRIPT_PATH}/.backup
DEPLOY_PATH=${SCRIPT_PATH}/.deploy
SCRIPT_LOG="${SCRIPT_PATH}/${SCRIPT_NAME%.*}.log"
TMP_LOG="${SCRIPT_PATH}/.${SCRIPT_NAME%.*}.log"
## 加载配置文件 - Load Configuration File
. "${SCRIPT_PATH}"/install.conf


## echo_log
function echo_log(){
    echo -e "$*" | tee -a ${SCRIPT_LOG}
}


## 判断状态码输出日志，异常不退出 - Logging status
function echo_cs(){
    if [[ "$?" -eq 0 ]];then
        echo_log "\e[1;32m$(date +'%F %T') [INFO] - $* Success! \e[0m"
    else
        echo_log "\e[1;31m$(date +'%F %T') [FAIL] - $* Fail! \e[0m"
    fi
}

## 判断状态码输出日志，异常不退出 - Logging Status, if fail exit
function echo_cs_exit(){
    if [[ "$?" -eq 0 ]];then
        echo_log "\e[1;32m$(date +'%F %T') [INFO] - $* Success! \e[0m"
    else
        echo_log "\e[1;31m$(date +'%F %T') [FAIL] - $* Fail! \e[0m"
        exit 1
    fi
}


## 创建备份目录和部署目录 - Create Backup directory
mkdir -p "${BACKUP_PATH}"
mkdir -p "${DEPLOY_PATH}"
if [ -f "${SCRIPT_LOG}" ];then
    > ${SCRIPT_LOG}
else
    touch ${SCRIPT_LOG}
fi

## 运行前置检查 - Running Pre Checks
function pre_check(){
    kubectl cluster-info >> /dev/null 2>&1
    echo_cs_exit "Check: kubernetes cluster-info"
    helm version | grep v3 >> /dev/null 2>&1
    echo_cs_exit "Check: helm version"
    test -n "${NAMESPACE}" >> /dev/null 2>&1
    echo_cs_exit "Check: NAMESPACE var configure"
    kubectl get ns "${NAMESPACE}" >> /dev/null 2>&1
    echo_cs_exit "Check: kubernetes namespace. \"kubectl create ns ${NAMESPACE}\""
    if [[ "${PV_ENABLED}" =~ [T/t][R/r][U/u][E/e] ]];then
        kubectl get pvc "${PVC_NAME}" -n "${NAMESPACE}" >> /dev/null 2>&1
        echo_cs "Check: kubernetes pvc. execute install.sh input 4 create pvc."
    fi
}


## 检查目录或文件是否存在 - Check if directory exists
function check_dir_file(){
    if [ ! -d "$1" ] && [ ! -f "$1" ] ;then
        echo_log "\e[1;31m$(date +'%F %T') Directory or file $1 does not exist, please check! \e[0m"
        exit 1
    fi
}


## 获取需要部署的product list - read product list
function get_product_list(){
    local product_conf=${SCRIPT_PATH}/product-list.conf
    check_dir_file "$product_conf"
    PRODUCT_LIST=""
    while read -r product || [[ -n ${product} ]]
    do
        if [[ ! $product =~ ^#.*$ ]] && [[ ! $product =~ ^$ ]] ;then
            PRODUCT_LIST="${PRODUCT_LIST} ${product}"
        fi
    done < "${product_conf}"
}


## 备份拷贝对应product至DEPLOY_PATH - create a deployment backup file
function init_helm_file(){
    cd "${SCRIPT_PATH}" || exit
    cp -rf "${DEPLOY_PATH}" ${BACKUP_PATH}/deploy_bak_$(date +'%Y%m%d%H%M')
    rm -rf "${DEPLOY_PATH}"/*
    for product in ${PRODUCT_LIST}
    do
        echo "$product"
        check_dir_file "../${product}"
        /bin/cp -rf ../${product} "${DEPLOY_PATH}"
        rm -rf "${DEPLOY_PATH}"/"${product}"/.git
    done
}


## 替换变量函数 - Substituting variables
function modify_file_func(){
    local KEY=$1
    local VALUE=$2
    if [ "$(uname)" == "Darwin" ]
    then
        echo "sed -i '' -e \"s#${KEY}#${VALUE}#g\""
        sed -i '' -e "s#${KEY}#${VALUE}#g" $(grep -rl "${KEY}" * | grep -e  "values.*.yaml" -e "configmap.*.yaml") > /dev/null 2>&1
    else
        sed -i  "s#${KEY}#${VALUE}#g" $(grep -rl ${KEY} ./*|grep  -e  "values.*.yaml" -e "configmap.*.yaml") > /dev/null 2>&1
        echo_cs "sed ${KEY} to ${VALUE}"
    fi
}


## 根据配置文件使用modify_file_func替换变量 - Replace variables according to configuration file
function modify_conf_file(){
    local FILE_PATH=$1
    while read -r line || [[ -n ${line} ]]
    do
        if [[ ! $line =~ ^#.*$ ]] && [[ ! $line =~ ^$ ]] ;then
            modify_key=$(echo "${line}" |cut -d '=' -f 1)
            #echo "${modify_key}"
            modify_file_func "@{${modify_key}}" "$(eval echo \$"$modify_key")"
        fi
    done < "${FILE_PATH}"

}


## init Realm
function cp_keycloak_realm(){
    if [[ -d "${DEPLOY_PATH}/fano-portal-ucharts" ]];then
        check_dir_file "${SCRIPT_PATH}/configuration/realmjson/${KEYCLOAK_DEFAULT_FANOLABS_REALM}"
        cd "${DEPLOY_PATH}/fano-portal-ucharts/charts/fano-portal-keycloak" || exit 1
        /bin/cp -rf "${SCRIPT_PATH}/configuration/realmjson/${KEYCLOAK_DEFAULT_FANOLABS_REALM}"  ./fanolabs-realm.json
        echo_cs_exit "/bin/cp -rf ${SCRIPT_PATH}/configuration/realmjson/${KEYCLOAK_DEFAULT_FANOLABS_REALM}  ${DEPLOY_PATH}/fano-portal-ucharts/charts/fano-portal-keycloak/fanolabs-realm.json"
        if [ "$(uname)" == "Darwin" ]
        then
            sed -i '' "s#portal-ootb.fano.ai#${PORTAL_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i '' "s#datapanel-ootb.fano.ai#${DATAPANEL_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i '' "s#intent-ootb.fano.ai#${PORTAL_INTENT_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i '' "s#callinter-ootb.fano.ai#${CALLINTER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i '' "s#stt-ootb.fano.ai#${STT_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i '' "s#tts-ootb.fano.ai#${TTS_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i '' "s#voiceprint-ootb.fano.ai#${VOICEPRINT_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i '' "s#navinter-ootb.fano.ai#${NAVINTER_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
        else
            sed -i "s#portal-ootb.fano.ai#${PORTAL_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i "s#datapanel-ootb.fano.ai#${DATAPANEL_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i "s#intent-ootb.fano.ai#${PORTAL_INTENT_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i "s#callinter-ootb.fano.ai#${CALLINTER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i "s#stt-ootb.fano.ai#${STT_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i "s#tts-ootb.fano.ai#${TTS_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i "s#voiceprint-ootb.fano.ai#${VOICEPRINT_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
            # sed -i "s#navinter-ootb.fano.ai#${NAVINTER_SERVER_URL}#g" ./fanolabs-realm.json > /dev/null 2>&1
        fi
        cd "${DEPLOY_PATH}" || exit 1
    fi
}


## 执行替换变量 - Combining function to modify helm chart
function modify_yaml(){
    init_helm_file
    cd "${DEPLOY_PATH}" || exit
    modify_conf_file "${SCRIPT_PATH}/install.conf"
    cp_keycloak_realm
}


## 部署函数 - Deployment function
function deploy_product(){
    local model=$1
    for product in ${PRODUCT_LIST}
    do
        if [[ "${model}" == "upgrade" ]] && [[ ${product} == "fano-common-ucharts" ]];then
            continue
        elif [[ "${model}" == "upgrade" ]] || [[ "${model}" == "install" ]]; then
            helm_release_name=${product%-ucharts*}
            echo "helm upgrade --install -f values-tag.yaml ${helm_release_name} . -n ${NAMESPACE}" > "${DEPLOY_PATH}"/"${product}"/deploy.sh
            helm upgrade --install -f "${DEPLOY_PATH}"/"${product}"/values-tag.yaml "${helm_release_name}" "${DEPLOY_PATH}"/"${product}" -n "${NAMESPACE}"
            echo_cs "helm upgrade --install -f .deploy/${product}/values-tag.yaml ${helm_release_name} .deploy/${product} -n ${NAMESPACE}" >> ${TMP_LOG} 2>&1
            t=2
            while test $t -gt 0
            do
                if [ $t -ge 10 ];then 
                echo -e "${t}\b\b\c"
                elif [ $t -eq 9 ];then
                echo -e "  \b\c"
                echo -e "\b${t}\b\c"
                else
                echo -e "${t}\b\c"
                fi
                sleep 1
                t=$((t-1))
            done
            # sleep 20
        else
            exit 1
        fi
    done
    cat "${TMP_LOG}" && rm -f "${TMP_LOG}"
}


## 卸载函数 - uninstalling helm chart
function uninstall_product(){
    echo -e "\e[1;31mUninstall product list: ${PRODUCT_LIST} \e[0m"
    read -p "Confirm uninstall? (yes/no, default no) :" is_uninstall
    [ -z "${is_uninstall}" ] && is_uninstall="no"
    if [[ "${is_uninstall}" =~ [Yy][Ee][Ss] ]];then
        uninstall_common="0"
        for product in ${PRODUCT_LIST}
        do
            helm_release_name=${product%-ucharts*}
            if [ ${helm_release_name} = "fano-common" ];then
                uninstall_common="1"
                continue
            fi
            helm uninstall ${helm_release_name} -n ${NAMESPACE}
            echo_cs "helm uninstall ${helm_release_name} -n ${NAMESPACE}" >> ${TMP_LOG} 2>&1
            t=2
            while test $t -gt 0
            do
                if [ $t -ge 10 ];then 
                echo -e "${t}\b\b\c"
                elif [ $t -eq 9 ];then
                echo -e "  \b\c"
                echo -e "\b${t}\b\c"
                else
                echo -e "${t}\b\c"
                fi
                sleep 2
                t=$((t-1))
            done
        done
        if [ "${uninstall_common}" = "1" ];then
            helm uninstall fano-common -n ${NAMESPACE}
            echo_cs "helm uninstall fano-common -n ${NAMESPACE}" >> ${TMP_LOG} 2>&1
        fi
        cat "${TMP_LOG}" && rm -f "${TMP_LOG}"
    else
        echo "$?" >> /dev/null 2>&1
        echo_cs "Cancel uninstall."
    fi
}


## 检查pod status - Check pod status
function check_service_status()
{
    local service_name=$1
    local namespace=$2
    result_status=False
    for pod_name in $(kubectl get po -n "${namespace}"  --sort-by=.status.startTime |grep "${service_name}"|awk '{print $1}' )
    do
        result_value=$(kubectl get po -n "${namespace}"  "${pod_name}" -o jsonpath="{.status.conditions[*].status}")
        if echo "$result_value"|grep  False >/dev/null 2>&1
        then
           result_status=False
           break
        else
           result_status=True
        fi
    done
    echo   ${result_status}
}


## 创建pv函数
function create_pv(){
    cd "${SCRIPT_PATH}/pvc" || exit 1
    check_dir_file "pvc-${PV_TYPE}.yaml"
    cp -rf pvc-${PV_TYPE}.yaml .pvc.yaml
    if [ "$(uname)" == "Darwin" ]
    then
        sed -i '' "s#@{PVC_NAME}#${PVC_NAME}#g" .pvc.yaml > /dev/null 2>&1
        sed -i '' "s#@{PVC_SIZE}#${PVC_SIZE}#g" .pvc.yaml > /dev/null 2>&1
    else
        sed -i  "s#@{PVC_NAME}#${PVC_NAME}#g" .pvc.yaml > /dev/null 2>&1 
        sed -i  "s#@{PVC_SIZE}#${PVC_SIZE}#g" .pvc.yaml > /dev/null 2>&1
    fi
    kubectl apply -f .pvc.yaml -n ${NAMESPACE}
    echo_cs "kubectl apply -f .pvc.yaml ${NAMESPACE}"
}




## 选项列表
function usage()
{
cat << EOF
1.Updated Yaml files
2.Install
3.Upgrade
4.Cerate pv
5.Uninstall
0.Exit
EOF
}


## 入口函数 - Overall Function
function main(){
    pre_check
    get_product_list
    echo_cs "deploy list: ${PRODUCT_LIST}"
    while true
    do
        usage
        read -rp "please input option: " choose
        case ${choose} in
        1)
            modify_yaml
        ;;
        2)
            deploy_product install
        ;;
        3)
            deploy_product upgrade
        ;;
        4)
            create_pv
        ;;
        5)
            uninstall_product
        ;;
        0)
            exit 0
        ;;
        esac
    done
}


main
